package org.biubiu0002.baiblog.im.processor;

import com.alibaba.fastjson.JSON;
import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.biubiu0002.baiblog.core.api.GroupUserApiService;
import org.biubiu0002.baiblog.im.async.event.SendChatMsgEvent;
import org.biubiu0002.baiblog.im.component.RabbitMqService;
import org.biubiu0002.baiblog.im.constants.MessageConstants;
import org.biubiu0002.baiblog.im.dto.ImUserDto;
import org.biubiu0002.baiblog.im.dto.message.Message;
import org.biubiu0002.baiblog.im.dto.message.MessageNotification;
import org.biubiu0002.baiblog.im.dto.message.MessageRequest;
import org.biubiu0002.baiblog.im.session.ServerSession;
import org.biubiu0002.baiblog.im.session.SessionMap;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author: biubiu0002
 * @Date: 2022/9/2 15:49
 **/
@Component
@Slf4j
@ChannelHandler.Sharable
public class ChatProcessor {

    @DubboReference
    private GroupUserApiService groupUserApiService;
    @Resource
    private RabbitMqService rabbitMqService;
    @Resource
    private SessionMap sessionMap;


    public void action(ServerSession session, Message message) {
        ImUserDto user = session.getUser();
        MessageRequest request = message.getMessageRequest();

        if (request != null && StringUtils.isNotBlank(request.getTo()) && StringUtils.isNotBlank(request.getContent())) {
            //先落库 后转发
            Integer type = request.getType();
            switch (type){
                case MessageConstants.MessageCommandType.PRIVATE_MESSAGE: {
                    //私聊
                    String to = request.getTo();
                    List<ServerSession> sessions = sessionMap.getSessionsByUid(to);
                    boolean online = true;
                    if (CollectionUtils.isEmpty(sessions)) {
                        log.debug("from {} to {} 目标离线", user.getUserUid(), to);
                        online = false;
                    }
                    //MQ异步处理 落库 回客户端ACK
                    SendChatMsgEvent sendChatMsgEvent = new SendChatMsgEvent();
                    sendChatMsgEvent.setMessage(message);
                    rabbitMqService.sendSendChatMsgEvent(sendChatMsgEvent);
                    //在线转发
                    if (online) {
                        //消息转发到to的每一个在线通道 发送WebSocketFrame帧
                        Message notifyMessage = this.assembleNotifyMessage(message);
                        TextWebSocketFrame response = new TextWebSocketFrame(JSON.toJSONString(notifyMessage));
                        for (ServerSession toSession : sessions) {
                            //构造 TextWebSocketFrame 文本帧 Notify报文
                            //可靠性第三步 向clientB发送Notify报文
                            toSession.getChannel().writeAndFlush(response);
                        }
                    }
                    break;
                }
                case MessageConstants.MessageCommandType.GROUP_MESSAGE:{
                    //群聊
                    //MQ异步处理 落库 回客户端ACK
                    SendChatMsgEvent sendChatMsgEvent = new SendChatMsgEvent();
                    sendChatMsgEvent.setMessage(message);
                    rabbitMqService.sendSendChatMsgEvent(sendChatMsgEvent);
                    //群聊转发
                    String groupUid = request.getTo();
                    List<String> groupUserUidList = groupUserApiService.getGroupUserUidList(groupUid);
                    //在线群成员除发送端的所有会话
                    List<ServerSession> onlineSessionList = sessionMap.getSessionListByUidListExceptSession(groupUserUidList, session.getSessionId());
                    Message notifyMessage = this.assembleNotifyMessage(message);
                    TextWebSocketFrame response = new TextWebSocketFrame(JSON.toJSONString(notifyMessage));
                    for (ServerSession serverSession : onlineSessionList) {
                        //发送Notify报文
                        serverSession.getChannel().writeAndFlush(response);
                    }
                    break;
                }
                default:{

                }
            }


        }


    }

    private Message assembleNotifyMessage(Message reqMessage) {
        Message message = new Message();
        MessageNotification messageNotification = new MessageNotification();
        MessageRequest messageRequest = reqMessage.getMessageRequest();
        BeanUtils.copyProperties(messageRequest, messageNotification);
        messageNotification.setMsgIdStr(String.valueOf(messageRequest.getMsgId()));
        message.setType(MessageConstants.MessageType.NOTIFICATION);
        message.setMessageNotification(messageNotification);
        return message;
    }




}
